package com.boot.netty.client.listener;

import com.boot.netty.client.config.NettyClientConfig;
import com.boot.netty.client.handler.NettyClientHandler;
import com.boot.netty.commons.exception.NettyException;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

/**
 * <p>Title:NettyClient</p>
 * <p>Description:netty客户端</p>
 * @version V1.0
 * @author ZhiPeng_Chen
 * @date: 2018/11/14
 */
@Slf4j
@Component
public class NettyClient {

    @Autowired
    private NettyClientConfig nettyClientConfig;

    private EventLoopGroup workGroup;
    private Bootstrap bootstrap;

    private static int retry = 0;

    public NettyClient(){
        init();
    }

    private void init(){
        this.workGroup= new NioEventLoopGroup();
        this.bootstrap = new Bootstrap();
        this.bootstrap.group(workGroup)
                .channel(NioSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO));
    }

    /**
     * 关闭服务器方法
     */
    @PreDestroy
    public void close() {
        log.info("关闭netty服务器");
        workGroup.shutdownGracefully();
    }

    public void connectServer(){
        Bootstrap handler = this.bootstrap.handler(new NettyClientHandler());
        ChannelFuture connect = handler.connect(nettyClientConfig.getServerIp(), nettyClientConfig.getPort());
        try {
            log.info("连接netty服务端 IP地址:[{}] 端口:[{}]",nettyClientConfig.getServerIp(),nettyClientConfig.getPort());
            connect.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            retry++;
            if (retry>nettyClientConfig.getMaxThreads()){
                log.error("Netty连接服务端失败超过最大次数{} 异常信息:{}",this.getClass().getName(),e.getMessage());
                throw new NettyException("Netty连接服务端失败超过最大次数");
            }
            log.error("连接服务端失败...尝试重连:{}次",retry);
        }finally {
            this.workGroup.shutdownGracefully();
        }
        this.connectServer();
    }
}
